"""
测试弹窗____测试按键的所有功能
"""
import tkinter as tk
import time
import threading
import re
import serial
from tkinter.font import Font


# 按键测试-串口通信-窗口
class KeySerPopup(tk.Toplevel):
    def __init__(self,
                 boolVar:tk.BooleanVar,                 # 返回值
                 ser_handle:serial.Serial,
                 exStr:str,                             # 匹配字符
                 title='key_name',    # 按键名称
                 wait_time = 10,                        # 等待时间
                 time_out = 1,
                 width = 350,
                 height = 150,
                 QT168_flag:bool=False,
                 **kwargs
                 ):
        super().__init__(**kwargs)
        self.focus()                    # 添加了获取焦点项
        self.ser = ser_handle
        # self.ser.write_timeout = time_out
        self.length = len(exStr)
        self.mask = re.compile(exStr)               # 编译正则,直接基于字节流试试
        # if QT168_flag
        self.exStr = exStr
        font = Font(family='微软雅黑', size=20)
        # 窗口还需要计时————大概模拟一下就是,10s
        self.second_count = wait_time
        # self.test_str = ExStr
        self.pupup_title = title        # 标题名称
        self.boolVar = boolVar

        self.flag = True


        self.title("请按下"+self.pupup_title)

        self.geometry(f"{width}x{height}+200+200")
        self.protocol("WM_DELETE_WINDOW", self.fail_btn_event)
        # 添加内容
        self.label = tk.Label(self, text=title, font=font)
        self.label.pack(pady=20)

        line_frame = tk.Frame(self)
        line_frame.pack(fill='x')
        line_frame.columnconfigure(0, weight=1)
        line_frame.columnconfigure(1, weight=1)
        pass_btn = tk.Button(line_frame, text="PASS", command=lambda :self.pass_btn_event())
        fail_btn = tk.Button(line_frame, text="FAIL", command=lambda :self.fail_btn_event())
        pass_btn.grid(row=0,column=0)
        fail_btn.grid(row=0,column=1)
        # close_btn = tk.Button(self, text="关闭", command=lambda :destory_popup(popup,strVar))
        # close_btn.pack()
        self.focus()

        self.bind("<Key>", self.keyboard_pass_fail_event)

        # 界面加载完毕后，开始倒计时
        t = threading.Thread(target=self.second_mul, daemon=True)
        t.start()
        # 界面加载完成后，启用子线程进行接收数据的处理
        t2 = threading.Thread(target=self.ser_read_re_match, daemon=True)
        t2.start()


    # 按键的读取信息---内置——————严格匹配
    def ser_read_re_match(self):
        data = ''
        try:
            while self.flag:
                temp = self.ser.read(1)      # 一位一位接收
                data += temp.decode(encoding='utf-8')
                print(data)
                if len(data) >= self.length and temp == b'':        # 当数据接收完成后，且长度大于指定长度，开始进行匹配
                    if self.mask.findall(data):       # 匹配成功
                        break
                    else:                                   # 匹配失败
                        data = ''                     # 清除上次接收的数据
                        # pass                                    # 不做处理
            self.pass_btn_event()  # pass
        except serial.serialutil.PortNotOpenError as ser_e:
            time.sleep(0.8)
            self.fail_btn_event()   # fail
            # print('串口未打开')
        except Exception as e:
            time.sleep(0.8)
            self.fail_btn_event()   # fail
            # print('串口未打开 或者 其他未知错误')

    # 用子线程进行倒计时减少
    def second_mul(self):
        while self.second_count > 0:
            self.second_count -= 1
            self.label.config(text="请按下"+f"{self.pupup_title}, 还有{self.second_count}秒")
            time.sleep(1)
        if self.second_count == 0:
            self.fail_btn_event()
            # self.case.result = False


    def pass_btn_event(self):
        self.second_count = -1  # 直接结束子线程
        # print('pass')
        self.boolVar.set(True)
        self.flag = False
        # self.case.test_result = ATestResult.PASS
        # if flag:
        #     self.case.result = True
        self.destroy()


    def fail_btn_event(self):
        self.second_count = -1  # 直接结束子线程
        # print('fail')
        self.boolVar.set(False)
        self.flag = False
        # self.case.test_result = ATestResult.FAIL
        # if flag:
        #     self.case.result = False
        self.destroy()

    def keyboard_pass_fail_event(self, event):
        # print(f"事件触发键盘输入:{event.char},对应的ASCII码:{event.keycode}")
        if event.keycode == 13:
            self.pass_btn_event()
        elif event.keycode == 8:
            self.fail_btn_event()
